//********************************************************
// PopupMenu.java
// Date: 4/4/2012
// Author: Jeff Xiong
//********************************************************
// Popup menu which displays the current contents of the players hand.
// Upon selecting a choice it uses Tile.java to place the proper image on the 
// board at the specified board location.
// ******************************************************
//Edit: Andrew
// ******************************************************

package functionality;

import java.awt.Color;
import java.util.ArrayList;

import javax.swing.JPanel;

public abstract class Tiles {

	private final LandScape _land;
	private final Building _building;
	private Point _point;
	private JPanel src;
	private ArrayList<Knight> knights = new ArrayList<Knight>();

	/**
	 * Constructor to create a Tiles object
	 * 
	 * @param String land
	 * @param int knightsRequried
	 * @param String building type
	 * @param int points
	 * @return none
	 */
	public Tiles(String land, int knightsReq, String building, int points) {
		_land = new LandScape(land, knightsReq);
		_building = new Building(building, points);
		_point = new Point();
	}

	/**
	 * Constructor to create a new Tiles object from an existing tile
	 * 
	 * @param Tiles t
	 * @return none
	 */
	public Tiles(Tiles t) {
		_land = new LandScape(t.getLandScape(), t.getQuantityKnights());
		_building = new Building(t.getBuildingStructure(), t.getWorth());
		_point = new Point(t.getTileLocation());
	}

	/**
	 * Returns the point worth of current Tiles object
	 * 
	 * @param Point p to set the point of the tile
	 * @return none
	 */
	public void setPoint(Point p) {
		_point=p;
	}

	/**
	 * Returns the JPanel of the current Tiles object
	 * 
	 * @param none
	 * @return JPanel src
	 */
	public JPanel getPanel() {
		return src;
	}

	/**
	 * Sets the JPanel of the current Tiles object
	 * 
	 * @param JPanel src
	 * @return none
	 */
	public void setPanel(JPanel p) {
		src=p;
	}

	/**
	 * Returns the point worth of the current Tiles object
	 * 
	 * @param none
	 * @return point worth of Tiles object based off of the Building of the Tiles object
	 */
	public Point getPoint() {
		return _point;
	}
	
	/**
	 * Returns the point worth of Tiles object
	 * 
	 * @param none
	 * @return int point worth of Tiles object based off of the Building of the Tile
	 */
	public int getWorth() {
		return _building.getPointsPossible();
	}

	/**
	 * Returns the number of knights currently on the Tiles object
	 * 
	 * @param none
	 * @return int number of knights on the Tiles object
	 */
	public int getQuantityKnights() {
		return knights.size();
	}

	/**
	 * Returns the Color class for the Top Knight of the current Tiles object
	 * 
	 * @param none
	 * @return Color class for top Knight on the Tiles object
	 */
	public Color getTopKnight() {
		if (knights.isEmpty())
			return Color.BLACK;
			
		return knights.get(getQuantityKnights() - 1).getColor();
		// TODO change line above(or actually the entire method) to 'return getKnightColor(getQuantityKnights() - 1);' instead of what it currently does?
	}
	
	/**
	 * Returns the Color class for the Top Knight of the current Tiles object
	 * 
	 * @param none
	 * @return Color class for top Knight on the Tiles object
	 */
	public Color getKnightColor(int x) {
		if (knights.isEmpty())return Color.BLACK;
			
		return knights.get(x).getColor();
	}
	
	/**
	 * Returns the Knight list 
	 * 
	 * @param none
	 * @return Knights (in ArrayList) of the current Tiles object
	 */
	public ArrayList<Knight> getKnightList() {
		return knights;
	}

	/**
	 * Returns the Point class for the current Tiles object
	 * 
	 * @param none
	 * @return Point class of the current Tiles object
	 */
	public Point getTileLocation() {
		return _point;
	}

	/**
	 * Returns the String Building Structure for the Tile
	 * 
	 * @param none
	 * @return String containing the Building Structure type
	 */
	public String getBuildingStructure() {
		return _building.getBuildingType();
	}

	/**
	 * Returns the String Landscape for the Tile
	 * 
	 * @param none
	 * @return String containing the Landscape type
	 */
	public String getLandScape() {
		return _land.getLandType();
	}

	/**
	 * Place the Knight in the Tile's 'knights' array
	 * 
	 * @param Knight
	 *            to be placed on tile
	 */
	// TODO remove commented code...
	/*public void placeKnight(Knight k) {
		//if (isFull())
		//	throw new IllegalStateException("Tile is full");

		// adds it to the end of the list
		knights.add(k);
	}*/
	public void placeKnight(ArrayList<Knight> t) {

		// TODO remove commented code...
		//if (isFull())
		//	throw new IllegalStateException("Tile is full");

		// adds it to the end of the list
		knights=t;
	}

	/**
	 * Sets the tile's location
	 * 
	 * @param x coordinate to be set
	 * @param y coordinate to be set
	 * @return none
	 */
	public void placeTile(int x, int y) {
		_point.setX(x);
		_point.setY(y);
	}

	/**
	 * Returns true if tile can no longer hold knights
	 * 
	 * @param none
	 * @return True if Tile is a castle and has more then 5 knights or if it is
	 *         another type and has more than 4 knights
	 */
	public boolean isFull() {
		if ((_building.getBuildingType().equalsIgnoreCase("castle"))
				&& getQuantityKnights() >= 5) {
			return true;// return true if its more then 5 tiles AND a castle
		} else if (getQuantityKnights() >= 4) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Returns true if equals tile
	 * 
	 * @param String land type
	 * @param String building type
	 * @return True if Tile consists of String land & String building;
	 * 			otherwise False
	 */
	public boolean equals(String land, String building) {
		if (_land.getLandType().equalsIgnoreCase(land)
				&& _building.getBuildingType().equalsIgnoreCase(building)) {
			return true;
		}
		return false;
	}
}